#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

//wait等待的是任意一个子进程的退出
//成功，返回子进程id, 失败，返回-1


//验证一:子进程运行5秒，父进程sleep10秒，子进程运行后进入僵尸状态，父进程睡眠醒后回收子进程，子进程从僵尸状态变死亡状态
//验证二:子进程运行5秒，父进程没有sleep, 在wait前后打印消息，结论是父进程会阻塞式等待子进程运行完毕，然后回收它

//void Worker()
//{
//    int cnt = 5;
//    while(cnt)
//    {
//        printf("I am child process, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt--);
//        sleep(1);
//    }
//}
//
//int main()
//{
//    pid_t id = fork();
//    if(id == 0)
//    {
//        //child
//        Worker();
//        exit(0);
//    }
//    else
//    {
//        printf("wait before: \n");
//        pid_t rid = wait(NULL);
//        printf("wait after: \n");
//        if(rid == id)
//        {
//            printf("wait success, pid: %d\n", getpid());
//        }
//        sleep(10);
//    }
//    return 0;
//}


//验证一:waitpid替换wait
//验证二:waitpid获取输出型参数status
//验证三:通过status提取exit code 和exit signal


void Worker()
{
    int cnt = 5;
    while(cnt)
    {
        printf("I am child process, pid: %d, ppid: %d, cnt: %d\n", getpid(),getppid(), cnt--);
        sleep(1);
    }
    //int a = 10;
    //a /= 0;
}

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        //child
        Worker();
        exit(10);
    }
    else
    {
        //father
        int status = 0;
        printf("wait before:\n");
        pid_t rid = waitpid(id, &status, 0); //id传-1表示等待任意一个进程, options传0表示阻塞式等待
        printf("wait after:\n");
        if(rid == id)
        {
            //printf("wait success, pid: %d\n", getpid());
            //printf("wait success, pid: %d, status: %d\n", getpid(), status); //不能对status整体使用
            //printf("wait success, pid: %d, exit signal: %d, exit code: %d\n", getpid(), status & 0x7f, (status >> 8)&0xFF);
            if(WIFEXITED(status))
            {
                printf("child process normal quit, exit code: %d!\n", WEXITSTATUS(status));
            }
            else
            {
                printf("child process quit except!\n");
            }
        }
    }
}


